﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NetAssist.Math;
//using System.Collections;

namespace NetAssistTests
{
  [TestClass()]
  public class BigRealTests
  {
    [TestMethod()]
    public void BigRealTest1()
    {
      BigReal r1 = .5;
      BigReal r1a = new BigReal(1, 2);
      BigReal r2 = new BigReal(1, 3);

      BigReal rAdd = BigReal.Add(r1, r2);
      BigReal rSubtract = BigReal.Subtract(r1, r2);
      BigReal rMultiply = BigReal.Multiply(r1, r2);
      BigReal rDivide = BigReal.Divide(r1, r2);
      BigReal rNegative = BigReal.Negate(r1);

      Assert.IsTrue(r1 == r1a);
      Assert.IsTrue(r1.ToString() == "1/2");
      Assert.IsTrue(r2.ToString() == "1/3");

      Assert.IsTrue(rAdd.ToString() == "5/6");
      Assert.IsTrue(rSubtract.ToString() == "1/6");
      Assert.IsTrue(rSubtract == rMultiply);
      Assert.IsTrue(rDivide == 1.5);
      Assert.IsTrue(rNegative == -.5);
    }

    [TestMethod()]
    public void BigRealTest2()
    {
      BigReal r1 = .5d;
      BigReal r2 = .5f;
      BigReal r3 = new BigReal(.5d);
      BigReal r4 = new BigReal(.5f);
      BigReal r5 = new BigReal(.5m);

      Assert.IsTrue(r1 == r2);
      Assert.IsTrue(r1 == r3);
      Assert.IsTrue(r1 == r4);
      Assert.IsTrue(r1 == r5);

      BigReal r6 = new BigReal(r1, 2);
      Assert.IsTrue(r6 == .25);


      BigReal r7 = new BigReal(-100, 3);
      BigReal r8 = new BigReal(100, 4);
      BigReal r9 = new BigReal(257, 10);

      Assert.IsTrue(r7.ToString() == "-33 1/3");
      Assert.IsTrue(r8.ToString() == "25");
      Assert.IsTrue(r9.ToString() == "25 7/10");

      Assert.IsTrue((int)r7 == -33);
      Assert.IsTrue((int)r8 == 25);

      Assert.IsTrue((long)r7 == -33);
      Assert.IsTrue((long)r8 == 25);

      Assert.IsTrue((double)r7 == -33.333333333333336);
      Assert.IsTrue((double)r8 == 25.0);

      BigReal rn1 = null;
      BigReal rn2 = null;

      Assert.IsTrue(rn1 == rn2);
      Assert.IsTrue(rn1 != r1);
      Assert.IsTrue(r1 != rn1);
      Assert.IsTrue(r7 != r8);


      Assert.IsTrue(r7 < r8);
      Assert.IsFalse(r7 > r8);

      Assert.IsTrue(r1 <= r2);
      Assert.IsTrue(r1 >= r2);

      Assert.IsTrue(BigReal.One() == 1);
      Assert.IsTrue(BigReal.Zero() == 0);
      Assert.IsTrue(BigReal.MinusOne() == -1);

      Assert.IsTrue(r8.GetHashCode() == (25.0).GetHashCode());

    }

    [TestMethod()]
    public void BigRealTest3()
    {
      BigReal r1 = new BigReal(.5d);
      BigReal r2 = new BigReal(.5d);
      BigReal r3 = new BigReal(.25d);
      BigReal r4 = new BigReal(.75d);

      Assert.IsTrue(BigReal.Equals(r1, r2));
      Assert.IsTrue(r1.Equals(r2));
      Assert.IsTrue(r1.CompareTo(r2) == 0);
      Assert.IsTrue(r1.CompareTo(r3) > 0);
      Assert.IsTrue(r1.CompareTo(r4) < 0);

      object o1 = new BigReal(.5d);
      object o2 = "Test";
      object o3 = null;

      Assert.IsTrue(r1.Equals(o1));
      Assert.IsFalse(r1.Equals(null));
      Assert.IsFalse(r1.Equals("Test"));
      Assert.IsFalse(r1.Equals(o3));

      try
      {
        Assert.IsTrue(r1.CompareTo(o1) == 0);
        var res = r1.CompareTo(o2) == 0;
        Assert.Fail();
      }
      catch (Exception ex)
      {
        Assert.IsTrue(ex.GetType() == typeof(ArgumentException));
      }

      BigReal r5 = new BigReal(2000, -5000);
      Assert.IsTrue(r5 == -.4);
      Assert.IsTrue(r5.ToString() == "-2/5");

      try
      {
        BigReal rex1 = new BigReal(1.0E+20);
        Assert.Fail();
      }
      catch (Exception ex)
      {
        Assert.IsTrue(ex.GetType() == typeof(ArgumentOutOfRangeException));
      }

      try
      {
        BigReal rex1 = new BigReal(1.0E-20);
        Assert.Fail();
      }
      catch (Exception ex)
      {
        Assert.IsTrue(ex.GetType() == typeof(ArgumentOutOfRangeException));
      }
    }
  }
}